package cn.boodqian.unittest;

import static org.junit.Assert.*;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.time.DateUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mortbay.log.Log;

import com.google.gson.Gson;

import cn.boodqian.airdata.*;

public class AirdataCacheTest {
	private String airdataJson = "{\"version\":0,\"length\":5,\"time\":\"Jul 5, 2013 00:00:00 AM\",\"data\":{\"so2\":[1,2,3,4,5],\"o3\":[1,2,3,4,5],\"no2\":[1,2,3,4,5],\"pm10\":[1,2,3,4,5],\"pm25\":[1,2,3,4,5]}}";
	private AirData airdata;
	private HashMap<String,Object> datamap;
	
	private void setupLogLevel()
	{
		//get the top Logger:
		Logger topLogger = java.util.logging.Logger.getLogger("");

		// Handler for console (reuse it if it already exists)
		Handler consoleHandler = null;
		//see if there is already a console handler
		for (Handler handler : topLogger.getHandlers()) {
			if (handler instanceof ConsoleHandler) {
				//found the console handler
				consoleHandler = handler;
				break;
			}
		}

		if (consoleHandler == null) {
			//there was no console handler found, create a new one
			consoleHandler = new ConsoleHandler();
			topLogger.addHandler(consoleHandler);
		}
		//set the console handler to fine:
		consoleHandler.setLevel(java.util.logging.Level.FINE);
		topLogger.setLevel(Level.FINE);
	}

	@Before
	public void setUp() throws Exception {
		setupLogLevel();
		airdata =  new Gson().fromJson(airdataJson, AirData.class);
		datamap = new HashMap<String,Object>();
		for( String type : Global.AirType ) {
			datamap.put(type, 6);
		}
	}

	@After
	public void tearDown() throws Exception {
	}
	
	@Test
	public void testMergeHour1() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addHours(olddate, 20);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.HOUR_OF_DAY);
		String datastr = new Gson().toJson(newdata);
		assertEquals( "{\"version\":0,\"length\":24,\"time\":\"Jul 5, 2013 8:00:00 PM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0]}}", 
				datastr );
	}
	
	@Test
	public void testMergeHour2() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addHours(olddate, 5);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.HOUR_OF_DAY);
		String datastr = new Gson().toJson(newdata);
		assertEquals( "{\"version\":0,\"length\":10,\"time\":\"Jul 5, 2013 5:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
	
	@Test
	public void testMergeHour3() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addHours(olddate, 30);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.HOUR_OF_DAY);
		String datastr = new Gson().toJson(newdata);
		assertEquals( "{\"version\":0,\"length\":24,\"time\":\"Jul 6, 2013 6:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}

	@Test
	public void testMergeDay1() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addDays(olddate, 27);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.DAY_OF_MONTH);
		String datastr = new Gson().toJson(newdata);
		assertEquals( "{\"version\":0,\"length\":30,\"time\":\"Aug 1, 2013 12:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
	
	@Test
	public void testMergeDay2() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addDays(olddate, 5);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.DAY_OF_MONTH);
		String datastr = new Gson().toJson(newdata);
		assertEquals( "{\"version\":0,\"length\":10,\"time\":\"Jul 10, 2013 12:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
	
	@Test
	public void testMergeDay3() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addDays(olddate, 40);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.DAY_OF_MONTH);
		String datastr = new Gson().toJson(newdata);
		assertEquals( "{\"version\":0,\"length\":30,\"time\":\"Aug 14, 2013 12:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
	
	@Test
	public void testMergeMonth1() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addMonths(olddate, 9);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.MONTH);
		String datastr = new Gson().toJson(newdata);
		System.out.println(datastr);
		assertEquals( "{\"version\":0,\"length\":12,\"time\":\"Apr 1, 2014 12:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[3.0,4.0,5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
	
	@Test
	public void testMergeMonth2() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addMonths(olddate, 5);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.MONTH);
		String datastr = new Gson().toJson(newdata);
		System.out.println(datastr);
		assertEquals( "{\"version\":0,\"length\":10,\"time\":\"Dec 1, 2013 12:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[1.0,2.0,3.0,4.0,5.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
		
	@Test
	public void testMergeMonth3() {
		Date olddate = airdata.getTime();
		Date newdate = DateUtils.addMonths(olddate, 20);
		AirData newdata = AirdataCache.merge(airdata, datamap, newdate, Calendar.MONTH);
		String datastr = new Gson().toJson(newdata);
		System.out.println(datastr);
		assertEquals( "{\"version\":0,\"length\":12,\"time\":\"Mar 1, 2015 12:00:00 AM\",\"data\":{\"co\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"so2\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"o3\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"no2\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm10\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0],\"pm25\":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,6.0]}}",
				datastr );
	}
}
